*************************************************************************************;
* This macro is to do firm fixed effect with cluster standard error               ;                                                                     ;
*(1) demean the independent variables using proc standard                            ;
*(2) regress the dependent variables on the demeaned independent variables           ;
*    fixed effec LSDV                                                                ;
* http://pages.stern.nyu.edu/~adesouza/sasfinphd/index/node60.html                   ;
* http://pages.stern.nyu.edu/~adesouza/sasfinphd/index/node61.html                   ;
* The coefficients from the above procedure are exactly the same as those from proc  ;
* glm (Frisch-Waugh Theorem). But, you do not have to create dummies (which is your  ;
* main problem). To get robust standard errors, you can simply use proc surveyreg    ;
* on step(3).                                                                        ;
* reference: http://pages.stern.nyu.edu/~adesouza/sasfinphd/index/node60.html        ;
* https://www.econjobrumors.com/topic/clustered-standard-errors-for-panel-data-in-sas;
*************************************************************************************;


%MACRO FEREG(y, x, firm, time, cluster,dataset, output );
data datatemp;
set &dataset;
run;

proc sort data=datatemp;
by &firm;
run;
/*
proc standard data=datatemp out=datatemp mean=0;
by &firm;
var &x;
run;
*/

/*** the coefficents are the same as the standard fe but the s.e may be slightly undereatimate ****/
/*** using the proc gml absorb insted of the 2-step method can get the correct coefs and s.e   ****/
ods output ParameterEstimates=tempout(keep=parameter estimate tvalue probt) DataSummary=tempsummary(keep=Label1 cValue1) FitStatistics=tempFitstat(keep=Label1 cValue1);
proc surveyreg data=datatemp;
cluster &cluster;   /* Robust standard errors with Clustered control */
model &y = &x ;
quit;
ods output close;

/*
  proc glm data=datatemp;
      absorb &firm;
      model &y =&x / solution noint;
	  quit;
   run;

*/


data tempcoef(keep=parameter estimate probt) tempt(keep=parameter tvalue);
set tempout;
run;

data tempcoef;
set tempcoef;
_TYPE="coef";
 if probt<0.1 then p='*  ';
 if probt<0.05 then p='** '; 
 if probt<0.01 then p='***';
value=trim(left(put(estimate,10.3)))||trim(left(p));
_N=(_N_-1)*2+1;
keep parameter _TYPE  value _N;
run;

data tempt;
set tempt;
_TYPE="t";
value=trim(left('['||trim(left(put(tvalue,10.3)))||']'));
_N=_N_*2;
keep parameter _TYPE value _N;
run;

data &output;
merge tempcoef tempt;
by _N;
drop _N;
run;

data tempsummary;
set tempsummary;
if _N_=1;  
keep  parameter _type value;
parameter="Nobs";
_type="Nobs";
value=cvalue1;
run;

data tempFitstat;
set tempFitstat;
keep  parameter _type value;
if _N_=1;
parameter="Rsquare";
_type="Rsquare";
value=cvalue1;
run;

data &output;
set &output tempsummary tempFitstat;
run;

proc datasets library=work nolist;
delete datatemp tempcoef tempt tempout;
quit;
run;

%mend FEREG;

/*
proc import out=dat
datafile = "C:\Users\Huyi_fin\Dropbox\testdata.csv"
dbms=csv replace;
getnames=yes;
run;



%let dataset=dat;
%let y=y;
%let x=x1 x2;
%let firm=firm;
%let time=t;
%let cluster=firm;
%let output=outset;



%FEREG(&y, &x, &firm, &time, &cluster,&dataset, &output );
*/





